home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / Libraries / DCLAP 6d / dclap6d / DClap / DView.cpp < prev    next >
Text File  |  1996-07-05  |  11KB  |  388 lines

  1. // DView.cp
  2. // d.g.gilbert
  3.  
  4.  
  5. #include "DView.h"
  6. #include "DViewCentral.h"
  7.  
  8. #include "DApplication.h"
  9.  
  10. //class DView : public DTaskMaster
  11.  
  12.  
  13. DView::DView(long id, Nlm_Handle nlmObject, long kind, DTaskMaster* superior, 
  14.     DList* subordinates) :
  15.         DTaskMaster(id, superior, subordinates),
  16.         fHresize(fixed),
  17.         fVresize(fixed),
  18.         fNlmObject(nlmObject),
  19.         fKind(kind)
  20. {
  21.     this->Initialize();
  22. }
  23.  
  24. DView::DView( long id, Nlm_Handle nlmObject, ResizeMethod Hresize, ResizeMethod Vresize,
  25.                  long kind, DTaskMaster* superior, DList* subordinates) :
  26.         DTaskMaster(id, superior, subordinates),
  27.         fHresize(Hresize),
  28.         fVresize(Vresize),
  29.         fNlmObject(nlmObject),
  30.         fKind(kind)
  31. {
  32.     this->Initialize();
  33. }
  34.  
  35. void DView::Initialize()
  36. {
  37.     Nlm_LoadRect(&fViewrect, 0, 0, 0, 0);
  38.     Nlm_LoadRect(&fSizerange, 0, 0, 32500, 32500);
  39.     if (fId) gViewCentral->RegisterView(this);  // do this for all new views ?!
  40.     this->SetNlmObject(fNlmObject);  
  41. }
  42.  
  43.     
  44. DView::~DView() 
  45. {
  46.         // !!!!!!!!!!!!!     FIXED 20 mar 94 w/ DeleteSubviews  !!!!!!!!!!!!!
  47.             
  48.         // we HAD a BIG memory leak here, as most of view methods
  49.         // are written assuming that deleting a superview will auto-delete all subviews
  50.         // BUT we never got around to fixing this, as we need to negotiate it w/ Vibrant
  51.         // who also removes subviews at each call to Nlm_Remove(), but it doesn't remove
  52.         // our Objects... just its own.  So whatever recursive call to RemoveAllSubviews
  53.         // we need to fiddle w/ fNlmObject so Nlm_Remove() doesn't try to removed gone objects
  54.         
  55.         // *****************
  56.  
  57.  
  58.     DeleteSubviews();
  59.  
  60.      
  61.     if (fNlmObject) {
  62.         Nlm_SetObject((Nlm_GraphiC)fNlmObject, NULL); //????
  63.  
  64.          // THIS IS A BIG HACK, but it may solve several of the messy crashes
  65.          // on Quit due to this messy vibrant-dclap interface
  66.          // (vibrant is insisting on drawing to non-existant views thru
  67.          //  its remove callbacks...)
  68.         if (!gApplication->fDone) Nlm_Remove(fNlmObject); 
  69.         }
  70.     fNlmObject= NULL;
  71.     gViewCentral->RemoveView(fId); // ?? this calls back here??
  72. }
  73.  
  74.  
  75.  
  76. void DView::DeleteSubviews()
  77. {
  78.     /// tricky part: tell superior Nlm object to forget about its subordinates, so it
  79.     /// doesn't try to delete them also !
  80.  
  81.     if (fSubordinates) {
  82.         Nlm_Handle aNlmHand = NULL;
  83.         Nlm_GraphiC aNlmChild= NULL;
  84.         //if (fNlmObject) aNlmChild= Nlm_GetChild(fNlmObject);
  85.         
  86.         long i, n= fSubordinates->GetSize();
  87.         for (i= 0; i<n; i++) {
  88.             DView* subord= (DView*)fSubordinates->At(i);
  89.             if (subord) {
  90.                 subord->DeleteSubviews(); 
  91.                 aNlmHand= Nlm_Parent(subord->fNlmObject);
  92.                 if (aNlmHand && aNlmHand == fNlmObject) 
  93.                     Nlm_SetChild((Nlm_GraphiC)fNlmObject, NULL);                
  94.                 delete subord;
  95.                 }
  96.             }        
  97.         fSubordinates->suicide(); //delete  ~DTaskMaster does this, but we need to do it now... ?
  98.         fSubordinates= NULL;
  99.         }
  100. }
  101.  
  102.  
  103. // from Vibrant vibincld.h // This should be public info !?
  104. typedef  struct  Nlm_graphicrec {
  105.   Nlm_GraphiC   next;
  106.   Nlm_GraphiC   parent;
  107.   Nlm_GraphiC   children;
  108.   Nlm_GraphiC   lastChild;
  109.   Nlm_GphPrcs   PNTR classptr;
  110.   Nlm_ActnProc  action;
  111.   Nlm_RecT      rect;
  112.   Nlm_Boolean   enabled;
  113.   Nlm_Boolean   visible;
  114.   Nlm_VoidPtr   thisobject; /* <<<add to hold DObjectPtr dgg++ */
  115. } Nlm_GraphicRec, Nlm_GraphicData, PNTR Nlm_GphPtr;
  116.  
  117. extern "C" void  Nlm_GetGraphicData PROTO((Nlm_GraphiC a, Nlm_GraphicData PNTR gdata));
  118. extern "C" void  Nlm_SetGraphicData PROTO((Nlm_GraphiC a, Nlm_GraphicData PNTR gdata));
  119. extern "C" void Nlm_SetNext PROTO((Nlm_GraphiC a, Nlm_GraphiC nxt));
  120. extern "C" Nlm_GraphiC Nlm_GetNext PROTO((Nlm_GraphiC a));
  121.  
  122. void DView::RemoveSubview( DView* aSubview, Nlm_Boolean doDeleteIt)
  123. {
  124.     if (aSubview) {
  125.         if (fSubordinates) {
  126.           Nlm_GraphicData  gdata;
  127.           Nlm_GraphiC theNlmview= (Nlm_GraphiC)aSubview->fNlmObject;
  128.             Nlm_Handle aNlmHand= Nlm_Parent( aSubview->fNlmObject);
  129.             if (aNlmHand && aNlmHand == fNlmObject) {
  130. #if 1
  131.                 Nlm_GetGraphicData((Nlm_GraphiC)fNlmObject, &gdata);
  132.                 if (gdata.children) {
  133.                     if (gdata.lastChild && gdata.lastChild != gdata.children) {
  134.                   Nlm_GraphiC last= NULL, next= NULL, p;
  135.                   p = gdata.children;
  136.                   while (p) {
  137.                     next = Nlm_GetNext(p);
  138.                       if (p == theNlmview) { // remove p from chain
  139.                                 if (last) Nlm_SetNext( last, next);
  140.                                 else gdata.children= next;
  141.                                 if (p == gdata.lastChild) gdata.lastChild= last;
  142.                       }
  143.                     else
  144.                         last = p;
  145.                     p= next;
  146.                       }
  147.                         }
  148.                     else if (gdata.children == theNlmview)
  149.                         gdata.children= NULL; // only child == theNlmview !?
  150.                     Nlm_SetGraphicData ((Nlm_GraphiC)fNlmObject, &gdata);
  151.                     }
  152. #else
  153.                 //Nlm_GraphiC chld= Nlm_GetChild( (Nlm_GraphiC)fNlmObject);
  154.                     // ! this alone is bad if there is more than one subview for this !
  155.                 Nlm_SetChild( (Nlm_GraphiC)fNlmObject, NULL);    
  156. #endif
  157.                 }            
  158.         fSubordinates->Delete( aSubview);
  159.             }
  160.         if (doDeleteIt) {
  161.             aSubview->DeleteSubviews(); 
  162.             delete aSubview;
  163.             }
  164.         }
  165. }
  166.  
  167. Nlm_CharPtr DView::GetTitle(char* title, ulong maxsize) 
  168.     if (title==NULL) title= (char*) MemNew(maxsize); //new char[maxsize];
  169.     Nlm_GetTitle( fNlmObject, title, maxsize);
  170.     return title;
  171. }
  172.     
  173. void DView::SetNlmObject(Nlm_Handle nlmObject) 
  174.     fNlmObject= nlmObject; 
  175.     if (fNlmObject) {
  176.         Nlm_SetObject((Nlm_GraphiC)fNlmObject, this);  
  177.         Nlm_ObjectRect( fNlmObject, &fViewrect);  
  178.         }
  179. }        
  180.  
  181. void DView::SetSuperior(Nlm_Handle newSuper) 
  182.     Nlm_SetParent( (Nlm_GraphiC)fNlmObject, (Nlm_GraphiC)newSuper); 
  183. }
  184.  
  185. void DView::SetWindow( DWindow* newWindow)
  186. {
  187.     if (!newWindow) Dgg_SetParentWindow( (Nlm_GraphiC)GetNlmObject(), NULL);
  188.   else Dgg_SetParentWindow( (Nlm_GraphiC)GetNlmObject(), 
  189.                                             (Nlm_WindoW) ((DView*)newWindow)->GetNlmObject() );
  190. }
  191.  
  192.  
  193. void DView::InvalRect(Nlm_RecT& r) 
  194. {
  195.     Nlm_WindoW w= Nlm_SavePort( fNlmObject);
  196. #ifdef WIN_MOTIF
  197.     this->Select();
  198. #endif
  199.     Nlm_InvalRect( &r);
  200.     // Nlm_RestorePort( w); //<<!! THIS CALLS UPDATER !!!!!!
  201.     if (w) Nlm_UseWindow (w); 
  202. }
  203.  
  204. void DView::Invalidate(void) 
  205.     Nlm_WindoW w= Nlm_SavePort( fNlmObject);
  206. #ifdef WIN_MOTIF
  207.     this->Select();
  208. #endif
  209.     Nlm_InvalObject(fNlmObject);  // naughty vib -- Nlm_Inval doesn't check current port...
  210.     // Nlm_RestorePort( w); //<<!! THIS CALLS UPDATER !!!!!!
  211.     if (w) Nlm_UseWindow (w); 
  212. }
  213.  
  214. void DView::SetTitle( char* title) 
  215.     Nlm_SetTitle( fNlmObject, title); 
  216.     Invalidate();
  217. }
  218.  
  219. void DView::Show(void) 
  220. {  
  221.     Invalidate(); //?? need now that we pulled out vibwndws/Nlm_RestorePort/Update call
  222.     Nlm_Update();
  223.     Nlm_Show(fNlmObject); 
  224. }
  225.  
  226. void DView::Hide(void) 
  227. {  
  228.     //Nlm_RecT  r;
  229.     //ViewRect( r);
  230.     //Nlm_EraseRect( &r);
  231.     Nlm_Hide(fNlmObject); 
  232.     //Nlm_Update();
  233. }
  234.  
  235. void DView::SetSizerange(Nlm_RecT r) 
  236. {
  237.     fSizerange= r;
  238.   ViewRect(fViewrect); // GetPosition(fViewrect);
  239.     fViewrect.left  = Max( fSizerange.left, fViewrect.left);
  240.     fViewrect.top   = Max( fSizerange.top, fViewrect.top);
  241.     fViewrect.right = Min( fViewrect.right, fSizerange.right);
  242.     fViewrect.bottom= Min( fViewrect.bottom, fSizerange.bottom);
  243.   this->SetPosition(fViewrect);
  244. }
  245.  
  246.  
  247.  
  248.     // !!?? Vibrant windows (& others) have no GetPosition callback & return 0 for position !!!????
  249.     // FIX THIS thru DView -- have one sane function (getposition/viewrect), not two at
  250.     // odds and incomplete -- use GetPosition when want to include scrollbar size
  251.     // or revise this somehow
  252.     
  253. void DView::ViewRect(Nlm_RecT& r) 
  254.     Nlm_ObjectRect(fNlmObject, &r);  
  255. }
  256.  
  257. void DView::GetPosition(Nlm_RecT& r) 
  258.     Nlm_GetPosition(fNlmObject, &r); 
  259.     if (Nlm_EmptyRect( &r)) Nlm_ObjectRect(fNlmObject, &r);
  260.     fViewrect= r; 
  261. }
  262.  
  263. void DView::SetPosition(Nlm_RecT& r) 
  264.     Nlm_RecT testr;
  265.     Nlm_GetPosition(fNlmObject, &testr); 
  266.     Boolean hasSetposition= (!Nlm_EmptyRect( &testr));
  267.     
  268.     if (hasSetposition) Nlm_SetPosition(fNlmObject, &r);
  269.     else Nlm_SetRect((Nlm_GraphiC)fNlmObject, &r);
  270.     fViewrect= r;
  271. }
  272.  
  273.  
  274. void DView::SizeToSuperview( DView* super, Boolean horiz, Boolean vert)
  275. {
  276. //#ifndef WIN_MSWIN
  277. #ifdef WIN_MAC
  278.     // the other win systems seem bothered by this...
  279.     // if this is enabled in motif, motif fails to move scrollbars !
  280.     
  281.     Nlm_RecT r, myr; 
  282.     // GetPosition includes size of scrollbars for slates, etc
  283.     super->ViewRect(r); //super->GetPosition(r);  
  284.     this->GetPosition(myr); //ViewRect(myr);   
  285.     if (horiz) {
  286.         myr.left = 0; 
  287.         myr.right= myr.left + (r.right - r.left) +1; 
  288.         }
  289.     if (vert) {
  290.         myr.top = 0;
  291.         myr.bottom = myr.top + (r.bottom - r.top) +1;
  292.         }
  293.     SetPosition( myr);
  294. #endif
  295. }
  296.  
  297.  
  298. void DView::ResizeSubviews(DView* superview, Nlm_PoinT sizechange)
  299. {
  300.     this->Resize(superview, sizechange);
  301.     if (fSubordinates) {
  302.         long i, n= fSubordinates->GetSize();
  303.         for (i= 0; i<n; i++) {
  304.             DView* subord= (DView*)fSubordinates->At(i);
  305.             if (subord) subord->ResizeSubviews(this, sizechange); 
  306.             }        
  307.         }
  308. }
  309.  
  310. void DView::Resize(DView* superview, Nlm_PoinT sizechange)
  311. {
  312.     Nlm_RecT    super;
  313.     short    wid, hgt, oldw, oldh, top, oldt, left, oldl;
  314.     
  315.     GetPosition(fViewrect); // mac: this one is *required*, in DTableView w/ scrollbars
  316.     //ViewRect(fViewrect); // mac: this one makes too small a resize for DTableView
  317.     left= oldl= fViewrect.left;
  318.     top= oldt= fViewrect.top;
  319.     wid= oldw= fViewrect.right  - left;
  320.     hgt= oldh= fViewrect.bottom - top;
  321.     
  322.     // want point & rect classes like MacApp that can iterate over to save us this dup?
  323.     switch (fHresize) {
  324.         case matchsuper: 
  325. #ifdef WIN_MAC
  326.     // problems w/ this w/ mswin, xwin -- need to fiddle to get it right
  327.             if (superview) { 
  328.                 superview->ViewRect(super);    
  329.                 left = 0; 
  330.                 wid  = super.right - super.left + 1; 
  331.                 }
  332.             else
  333.                 wid += sizechange.x;
  334.             break;
  335. #endif
  336.         case relsuper    : wid += sizechange.x; break;
  337.         case moveinsuper: left += sizechange.x; break;
  338.         case calculate: wid = this->CalculateNewSize(false, wid, sizechange.x); break;
  339.         case fixed    :
  340.         default            : break;
  341.         }
  342.         
  343.     switch (fVresize) {
  344.         case matchsuper: 
  345. #ifdef WIN_MAC
  346.             if (superview) { 
  347.                 superview->ViewRect(super);    
  348.                 top = 0;
  349.                 hgt = super.bottom - super.top + 1;
  350.                 }
  351.             else
  352.                 hgt += sizechange.y;
  353.             break;
  354. #endif
  355.         case relsuper    : hgt += sizechange.y; break;
  356.         case moveinsuper: top += sizechange.y; break;
  357.         case calculate: hgt = this->CalculateNewSize(true, hgt, sizechange.y); break;
  358.         case fixed        :
  359.         default                : break;
  360.         }
  361.     
  362.     if (oldw != wid || oldh != hgt || oldl != left || oldt != top) {
  363.         fViewrect.left  = Max( fSizerange.left, left);
  364.         fViewrect.top   = Max( fSizerange.top, top);
  365.         fViewrect.right = Min( Max( fViewrect.left+1, fViewrect.left + wid), fSizerange.right);
  366.         fViewrect.bottom= Min( Max( fViewrect.top+1, fViewrect.top + hgt), fSizerange.bottom);
  367.         this->Select(); // motif requires !!
  368.       this->SetPosition(fViewrect);
  369.       
  370. #if 0
  371. //#ifdef WIN_MOTIF
  372.       // !! in Motif, nothing is drawn in resized area, and scrollbars, etc, disappear 
  373.       this->Select(); 
  374.       this->Hide();  
  375.       this->Show();  
  376. #endif
  377.       }
  378. }
  379.  
  380.